//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Pivot;

namespace OpenLS.Spreadsheet
{
    partial class Cell
    {
        ExtraCellData _extraData;
        private ExtraCellData EnsureExtraData
        {
            get
            {
                if (!HasExtraData)
                    EnsurePromoted();
                if (!HasExtraData)
                    _extraData = new ExtraCellData();
                return ExtraData;
            }
        }
        private ExtraCellData ExtraData
        {
            get
            {
                Contract.Requires(_extraData != null);
                Contract.Ensures(Contract.Result<ExtraCellData>() != null);
                return _extraData;
            }
        }
        void ForgetExtraData()
        {
            if (HasExtraData)
            {
                if (_extraData.IsDefault)
                    _extraData = null;
            }
        }
        bool HasExtraData { get { return _extraData != null; } }
        class ExtraCellData
        {
            public ExtraCellData()
            {
                RowSpan = 1;
                ColumnSpan = 1;
            }

            private TableBase _tableOrPivotTable;
            internal TableBase TableBase
            {
                get { return (TableBase) _tableOrPivotTable; }
                set { _tableOrPivotTable = value; }
            }

            /*internal Pivot.PivotTableDefinition PivotTable
            {
                get { return (PivotTableDefinition) _tableOrPivotTable; }
                set { _tableOrPivotTable = value; }
            }
            */

            public DataBarInformation DataBar
            {
                get
                {
                    if (_conditionalFormattingInformation == null)
                        return null;
                    return this._conditionalFormattingInformation.DataBar;
                }
                set
                {
                    if (value != null)
                    {
                        EnsureConditionalInformation().DataBar = value;
                    }
                    else if (_conditionalFormattingInformation != null)
                    {
                        _conditionalFormattingInformation.DataBar = value;
                        ForgetConditionFormattingInformation();
                    }
                }
            }

            public IconSetInformation Icon
            {
                get
                {
                    if (_conditionalFormattingInformation == null)
                        return null;
                    return this._conditionalFormattingInformation.Icon;
                }
                set
                {
                    if (value != null)
                    {
                        EnsureConditionalInformation().Icon = value;
                    }
                    else if (_conditionalFormattingInformation != null)
                    {
                        _conditionalFormattingInformation.Icon = value;
                        ForgetConditionFormattingInformation();
                    }
                }
            }
            void ForgetConditionFormattingInformation()
            {
                if (_conditionalFormattingInformation.IsDefault)
                    _conditionalFormattingInformation = null;
                
            }

            private ConditionalFormattingInformation EnsureConditionalInformation()
            {
                if (_conditionalFormattingInformation == null)
                    _conditionalFormattingInformation = new ConditionalFormattingInformation();
                return _conditionalFormattingInformation;
            }
            public ColorScaleInformation ColorScale
            {
                get
                {
                    if (_conditionalFormattingInformation == null)
                        return null;
                    return _conditionalFormattingInformation.ColorScale;
                }
                set
                {
                    if (value != null)
                    {
                        EnsureConditionalInformation().ColorScale = value;
                    }
                    else if (_conditionalFormattingInformation != null)
                    {
                        _conditionalFormattingInformation.ColorScale = value;
                        ForgetConditionFormattingInformation();
                    }
                }
            }
            public DifferentialStyleRecord DifferentialStyleRecord
            {
                get
                {
                    if (_conditionalFormattingInformation == null)
                        return null;
                    return _conditionalFormattingInformation.DifferentialStyleRecord;
                }
                set
                {
                    if (value != null)
                    {
                        EnsureConditionalInformation().DifferentialStyleRecord = value;
                    }
                    else if (_conditionalFormattingInformation != null)
                    {
                        _conditionalFormattingInformation.DifferentialStyleRecord = value;
                        ForgetConditionFormattingInformation();
                    }
                }
            }
            public void OnCellChanged (Cell owner)
            {
                if (ConditionalFormatting == null)
                    return;
                foreach (var v in ConditionalFormatting)
                    v.Apply(Spreadsheet.ConditionalFormatting.ApplyReason.ValueChanged);
            }
            public List<ConditionalFormatting> ConditionalFormatting
            {
                get
                {
                    if (_conditionalFormattingInformation == null)
                        return null;
                    return this._conditionalFormattingInformation.ConditionalFormattings;
                }
                set
                {
                    if (value != null)
                    {
                        EnsureConditionalInformation().ConditionalFormattings = value;
                    }
                    else if (_conditionalFormattingInformation != null)
                    {
                        _conditionalFormattingInformation.ConditionalFormattings = value;
                        ForgetConditionFormattingInformation();
                    }
                }
            }
            ConditionalFormattingInformation _conditionalFormattingInformation;
            public RichTextParagraph Paragraph;
            public int RowSpan;
            public int ColumnSpan;
            public Hyperlink hl;
            public Comment Comment;
            public string FormulaWithoutEqual;
            public bool HasDependents { get { return _dependencies != null; } }
            HashListNoDuplicate<IDependencyNode> _dependencies;
            private HashListNoDuplicate<RangeNodeBase> rangeDependencies;

            public HashListNoDuplicate<IDependencyNode> Dependencies
            {
                get
                {
                    if (_dependencies == null)
                        _dependencies = new HashListNoDuplicate<IDependencyNode>();
                    return _dependencies;
                }
            }
            public HashListNoDuplicate<RangeNodeBase> RangeDependencies
            {
                get
                {
                    if (rangeDependencies == null)
                        rangeDependencies = new HashListNoDuplicate<RangeNodeBase>();
                    return rangeDependencies;
                }
            }
            public void ForgetRangeDependencies()
            {
                rangeDependencies = null;
            }
            public bool IsDefault
            {
                get
                {
                    return TableBase == null && ColorScale == null && DataBar == null &&  DifferentialStyleRecord == null && FormulaWithoutEqual == null && RowSpan == 1 && ColumnSpan == 1 && hl == null && Comment == null &&
                        this._conditionalFormattingInformation == null && Tag == null && 
                        (_dependencies == null || _dependencies.Count == 0) &&
                        (rangeDependencies == null || rangeDependencies.Count == 0) && Paragraph == null;
                }
            }

            internal object Tag
            {
                get; set;
            }

            internal void ResetConditionalFormattingInformation(ConditionalFormatting conditionalFormatting)
            {
                Contract.Assert(_conditionalFormattingInformation.ConditionalFormattings.Contains(conditionalFormatting));
                if (_conditionalFormattingInformation.ConditionalFormattings.Count == 1)
                {
                    _conditionalFormattingInformation = null;
                    return;

                }
                _conditionalFormattingInformation.Remove(conditionalFormatting);
            }

        }

        public void AddConditionalFormatting(ConditionalFormatting conditionalFormatting)
        {
            Contract.Requires(conditionalFormatting != null);
            if (ConditionalFormattings == null)
            {
                var list = new List<ConditionalFormatting>();
                ConditionalFormattings = list;
            }
            ConditionalFormattings.Add(conditionalFormatting);
        }
    }
}
